/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <stdio.h>
#include <stdlib.h>
#include <ms_rtos.h>

static size_t
stdin_read(FILE *fp, char *bp, size_t n)
{
    return ms_io_read(0, bp, n);
}

static size_t
stdout_write(FILE *fp, const char *bp, size_t n)
{
    return ms_io_write(1, bp, n);
}

static size_t
stderr_write(FILE *fp, const char *bp, size_t n)
{
    return ms_io_write(2, bp, n);
}

static struct File_methods _stdin_methods = {
    .read = stdin_read
};

static struct File_methods _stdout_methods = {
    .write = stdout_write,
};

static struct File_methods _stderr_methods = {
    .write = stderr_write,
};

static struct File _stdin = {
    .vmt = &_stdin_methods
};

static struct File _stdout = {
    .vmt = &_stdout_methods
};

static struct File _stderr = {
    .vmt = &_stderr_methods
};

struct File *const stdin  = &_stdin;
struct File *const stdout = &_stdout;
struct File *const stderr = &_stderr;

/**
 * @brief Error print.
 *
 * @param[in] string            Format string
 * @param[in] expression        Expression string
 * @param[in] line              Line number in file
 * @param[in] filename          File name
 *
 * @return N/A
 */
void __eprintf(const char *string, const char *expression,
               unsigned int line, const char *filename)
{
    ms_printk(MS_PK_ERR, string, expression, line, filename);
    _exit(EXIT_FAILURE);
}

void __aeabi_idiv0(void)
{
    ms_printk(MS_PK_ERR, "Div 0 error\n");
    _exit(EXIT_FAILURE);
}

void __aeabi_ldiv0(void)
{
    ms_printk(MS_PK_ERR, "Div 0 error\n");
    _exit(EXIT_FAILURE);
}
